package priv.dajie.tzzq.core;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import priv.dajie.tzzq.bot.BotManager;
import priv.dajie.tzzq.bot.buff.BuffBot;
import priv.dajie.tzzq.bot.buff.BuffUser;
import priv.dajie.tzzq.bot.c5.C5Bot;
import priv.dajie.tzzq.bot.exception.BuyException;
import priv.dajie.tzzq.bot.exception.NetworkException;
import priv.dajie.tzzq.bot.steam.SteamBot;
import priv.dajie.tzzq.model.Code;
import priv.dajie.tzzq.model.CompareItem;
import priv.dajie.tzzq.bot.model.*;
import priv.dajie.tzzq.common.DruidUtils;

import java.io.*;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class SteamAutoBuy implements Runnable{
    private C5Bot c5Bot;
    private BuffBot buffBot;
    private BuffUser buffUser;
    private SteamBot steamBot;


    private Logger logger = LogManager.getLogger(this.getClass().getName());
    private BigDecimal rate = new BigDecimal("0.85");

    private final String COMPARE_SQL = "SELECT distinct steam_max.name, steam_max.price, GET_MAX_PRICE_2(c5_buff_maxpro.c5sp,c5_buff_maxpro.buffsp) as '最高出售价格',GET_MAX_PRICE_2(c5_buff_maxpro.c5bp,c5_buff_maxpro.buffbp) as '最高求购价格', GET_MAX_PRICE_2(c5_buff_maxpro.c5bp,c5_buff_maxpro.buffbp) / steam_max.price as '最大差价', GET_MIN_MULTIPLE_2(steam_max.price,c5_buff_maxpro.c5bp,c5_buff_maxpro.buffbp) as '最大差价比',GET_MAX_PLAT_2(c5_buff_maxpro.c5bp,c5_buff_maxpro.buffbp) as '最大差价比平台', GET_ID_MAX_2(c5_buff_maxpro.c5bp,c5_id,c5_buff_maxpro.buffbp, buff_id) as '平台id', steam_max.steam_name, steam_max.nameid, c5_buff_maxpro.c5sp,c5_buff_maxpro.buffsp,c5_buff_maxpro.c5bp,c5_buff_maxpro.buffbp,buff_id,c5_id\n" +
            "FROM c5_buff_maxpro LEFT JOIN steam_max\n" +
            "ON c5_buff_maxpro.steam_name = steam_max.steam_name\n" +
            "WHERE GET_MAX_PRICE_2(c5_buff_maxpro.c5bp,c5_buff_maxpro.buffbp) / steam_max.price > 0.6\n" +
            "AND date > date_sub(curdate(),interval 1 day)\n"+
            "ORDER BY 最大差价比 DESC\n" +
            "LIMIT 0,1000\n";

    public SteamAutoBuy(BigDecimal rate){
        this(BotManager.getSteamBot(), BotManager.getBuffBot(), BotManager.getC5Bot(), -1, -1, rate);
    }

    public SteamAutoBuy(SteamBot steamBot, BuffBot buffBot, C5Bot c5Bot, int c5SpiderThreadNum, int buffSpiderThreadNum, BigDecimal rate) {
        this.steamBot = steamBot;
        this.buffBot = buffBot;
        this.buffUser = buffBot.getBuffUser();
        this.c5Bot = c5Bot;
        this.rate = rate;
//        if(c5SpiderThreadNum == -1 || buffSpiderThreadNum == -1) {
//            Properties properties = new Properties();
//            InputStream inputStream = null;
//            try {
//                inputStream = new FileInputStream(System.getProperty("user.dir") + "/config/run.properties");
//                properties.load(inputStream);
//                c5SpiderThreadNum = Integer.parseInt(properties.getProperty("c5-spider-num"));
//                buffSpiderThreadNum = Integer.parseInt(properties.getProperty("buff-spider-num"));
//            } catch (IOException e) {
//                e.printStackTrace();
//            }finally {
//                if (inputStream!=null) {
//                    try {
//                        inputStream.close();
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//        }
//        // 设置线程
//        this.c5SpiderThreadNum = c5SpiderThreadNum;
//        this.buffSpiderThreadNum = buffSpiderThreadNum;
//        buffSpiderThreads = new Thread[buffSpiderThreadNum];
//        c5SpiderThreads = new Thread[c5SpiderThreadNum];
//        buffSpiders = new BuffSpider[buffSpiderThreadNum];
//        c5Spiders = new C5Spider[c5SpiderThreadNum];
//
//        for (int i = 0; i < c5SpiderThreadNum; i++) {
//            c5Spiders[i] = new C5Spider(SpiderMode.NEWTABLE);
//            c5SpiderThreads[i] = new Thread(c5Spiders[i]);
//        }
////        System.out.println(buffSpiderThreadNum);
//        for (int i = 0; i < buffSpiderThreadNum; i++) {
//            buffSpiders[i] = new BuffSpider(buffUser, SpiderMode.NEWTABLE);
//            buffSpiderThreads[i] = new Thread(buffSpiders[i]);
//        }
    }

    public SteamAutoBuy(SteamBot steamBot, BuffBot buffBot, C5Bot c5Bot, BigDecimal rate){
        this(steamBot, buffBot, c5Bot, -1, -1, rate);

    }

//    public void startAllSpider() throws InterruptedException { // 启动buff和c5爬虫  待测试 2019.5.23
//        SpiderInfo c5Info = C5Infos.getC5Info(); // 获取c5信息
//        SpiderInfo buffInfo = BuffInfos.getBuffInfo(); // 获取buff信息
//        for (int i = 0; i < c5SpiderThreadNum; i++) { // 激活c5线程
//            logger.info("启动c5Spider线程："+i);
////            System.out.println("启动c5Spider线程："+i);
//            c5Spiders[i].setSpiderInfo(c5Info);
//            c5SpiderThreads[i].start();
//        }
//        for (int i = 0; i < c5SpiderThreadNum; i++) { // 防止过早激活buff线程
//            c5SpiderThreads[i].join();
//        }
//        for (int i = 0; i < buffSpiderThreadNum; i++) { // 激活buff线程
//            logger.info("启动buffSpider线程："+i);
////            System.out.println();
//            buffSpiders[i].setSpiderInfo(buffInfo);
//            buffSpiderThreads[i].start();
//        }
//        for (int i = 0; i < buffSpiderThreadNum; i++) { // 防止过早激活buff线程
//            buffSpiderThreads[i].join();
//        }
//    }

    public void saveRunTime() { // 保存当次运行spider的时间
        File file = new File(System.getProperty("user.dir") + "/data/steamSpiderRunTime");
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            FileWriter fileWriter = new FileWriter(file);
            fileWriter.write(System.currentTimeMillis() + "");
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Long loadRunTime() { // 获取上次运行spider的时间
        File file = new File(System.getProperty("user.dir") + "/data/steamSpiderRunTime");
        String time = "0";
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            time = reader.readLine();
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Long.valueOf(time);
    }

    public List<CompareItem> compare(){
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        List<CompareItem> items = new ArrayList<>();
        try {
            connection = DruidUtils.getConnection();
            statement = connection.createStatement();
            resultSet = statement.executeQuery(COMPARE_SQL);
            while(resultSet.next()){
                String steamName = resultSet.getString("steam_name");
                String nameid = resultSet.getString("nameid");
                String c5ID = resultSet.getString("c5_id");
                String buffID = resultSet.getString("buff_id");
                BigDecimal price = resultSet.getBigDecimal("price");
                BigDecimal c5NeedPirce = resultSet.getBigDecimal("c5bp");
                BigDecimal buffNeedPrice = resultSet.getBigDecimal("buffbp");
                items.add(new CompareItem(steamName, nameid, c5ID, buffID, c5NeedPirce, buffNeedPrice, price));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DruidUtils.close(connection, statement, resultSet);
        }
        return items;
    }

    public SteamAnalysisItem checkPrice(CompareItem compareItem){
        logger.info("正在检查："+compareItem.getSteamName());
        List<BuyItem> c5BuyItems;
        List<BuyItem> buffBuyItems;
        try {
            c5BuyItems = c5Bot.getBuyItems(compareItem.getC5ID(), NameType.ID);
            buffBuyItems = buffBot.getBuyItems(compareItem.getBuffID(), NameType.ID);
        }catch (NetworkException e){
            logger.error(e);
            return new SteamAnalysisItem(Code.ERROR, null);
        }
        // 获取最高的求购价格
        if(buffBuyItems.size()==0 || c5BuyItems.size()==0){
            logger.info("求购数量 不符合要求-> buff求购数量:"+buffBuyItems.size() + " | c5求购数量:"+c5BuyItems.size());
            return new SteamAnalysisItem(Code.GOODLESS, null);
        }

        BigDecimal buffPrice = buffBuyItems.get(0).getPrice();
        BigDecimal c5Price = c5BuyItems.get(0).getPrice();
        BigDecimal steamPrice = steamBot.getMinPrice(compareItem.getNameid());
//        double maxPirce = buffPrice >= c5Price ? buffPrice : c5Price;
//         售价比例与平台比例
//        double steamRate = maxPirce / steamPrice;
        BigDecimal buffRate = buffPrice.divide(steamPrice);
        BigDecimal c5Rate = c5Price.divide(steamPrice);
//        double platformRate = buffPrice / c5Price;
        if(!(buffRate.compareTo(rate)>=0 && c5Rate.compareTo(rate)>=0)) {
            logger.info("收益比 不符合要求-> buff收益比: "+ buffRate + " | c5收益比: "+ c5Rate);
            return new SteamAnalysisItem(Code.LOW_RATE, null);
        }

        // 符合比例的数量
        int c5PassCount = passCount(steamPrice, c5BuyItems);
        int buffPassCount = passCount(steamPrice, buffBuyItems);
        if(!(c5PassCount>=2 && buffPassCount>=2 || c5PassCount+buffPassCount>=5)) { // 两个平台求购小于2
                List<SellItem> c5SellItems = c5Bot.getSellItems(compareItem.getC5ID(), NameType.ID);
                List<SellItem> buffSellItems = buffBot.getSellItems(compareItem.getBuffID(), NameType.ID);
                if (!(c5SellItems.get(0).getPrice().divide(steamPrice, 3, BigDecimal.ROUND_CEILING).compareTo(new BigDecimal("1.2")) >=0
                        && buffSellItems.get(0).getPrice().divide(steamPrice,3,BigDecimal.ROUND_CEILING).compareTo(new BigDecimal("1.2")) >= 0)) {
                    logger.info("求购数量、出售价格 不符合要求 -> c5PassCount:" + c5PassCount + " | buffPassCount:" + buffPassCount);
                    return new SteamAnalysisItem(Code.LOW_RATE, null);
                }
        }

        // 获取c5的销售历史
        HistoryPrices c5HistoryPrices = c5Bot.getHistoryPrice(compareItem.getC5ID());
        double c5HistoryRate = c5HistoryPrices.deviationRate(7);
        int c5Effective = c5HistoryPrices.effective(7);
        if(!((c5HistoryRate < 0.40) && c5Effective >= 3)){ // 历史售价与当前求购价比例在0.8-1.12之间且7天销售量大于5
            logger.info("历史售价均值 不符合要求-> 偏差比:"+c5HistoryRate + " | c5周销售量: "+c5Effective);
            return new SteamAnalysisItem(Code.HIGH_VOL, null);
        }
        // 获取Buff的销售历史
        HistoryPrices buffHistoryPrices = buffBot.getHistoryPrice(compareItem.getBuffID());
        double buffHistoryRate = buffHistoryPrices.deviationRate(7);
        int buffEffective = buffHistoryPrices.effective(7);
        if(!((buffHistoryRate < 0.50) &&buffEffective >= 3)){ // 历史售价与当前求购价比例在0.8-1.12之间且7天销售量大于5
            logger.info("历史售价均值 不符合要求-> 偏差比:"+buffHistoryRate + " | buff周销售量: "+buffEffective);
            return new SteamAnalysisItem(Code.HIGH_VOL, null);
        }


        logger.info(compareItem.getSteamName()+":符合购买要求");
        List<SteamSellItem> steamSellItems = steamBot.getSellList(compareItem.getSteamName());
        return new SteamAnalysisItem(Code.SUCCESS, steamSellItems.get(0));
    }


    private int passCount(BigDecimal steamPrice, List<BuyItem> buyItems){
        int count = 0;
        for(BuyItem item : buyItems){
            if(item.getPrice().divide(steamPrice).compareTo(rate)>0){
                count+=item.getNum();
            }
        }
        return count;
    }


    @Override
    public void run() {
        List<CompareItem> compareItems = compare();
        System.out.println("匹配数量："+compareItems.size());
        double sum = 0;
        double buySum = 0;
//        List<CompareItem> buyList = new ArrayList<>();
        for(CompareItem compareItem : compareItems){
            SteamAnalysisItem steamAnalysisItem = checkPrice(compareItem);
            if (steamAnalysisItem.getCode() == Code.SUCCESS) {
                try {
                    steamBot.buy(steamAnalysisItem.getSteamSellItem());
                } catch (BuyException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    public static void main(String[] args){

//        SteamAutoBuy steamAutoBuy = new SteamAutoBuy(0.7);

    }


}
